<template>
  <div>
    <el-form
      ref="paramsFormRef"
      :model="formData"
      :rules="formRules"
      label-width="120px"
      label-position="top"
    >    
      <el-form-item label="Body参数类型" prop="type">
        <el-select
          v-model="formData.type"
          placeholder="请选择Body参数类型"
          style="width: 100%;"
          @change="handleTypeChange"
        >
          <el-option label="none" value="none" />
          <el-option label="form-data" value="form-data" />
          <el-option label="x-www-form-urlencoded" value="x-www-form-urlencoded" />
          <el-option label="raw" value="raw" />
        </el-select>
      </el-form-item>
      
      <el-form-item v-if="formData.type === 'raw'" label="raw类型" prop="rawType">
        <el-select
          v-model="formData.rawType"
          placeholder="请选择raw类型"
          style="width: 100%;"
          @change="handleRawTypeChange"
        >
          <el-option label="Text" value="Text" />
          <el-option label="JavaScript" value="JavaScript" />
          <el-option label="JSON" value="JSON" />
          <el-option label="HTML" value="HTML" />
          <el-option label="XML" value="XML" />
        </el-select>
      </el-form-item>
      
      <template v-if="['form-data','x-www-form-urlencoded'].includes(formData.type)">
        <div class="header-content">
			<div style="margin-bottom: 0.3125rem;">
				<el-button type="primary" text size="small" @click="handleEditHeader(-1, null)">添加参数</el-button>
			</div>
			<el-table :data="content" border style="width: 100%">
				<el-table-column prop="name" label="参数名称" />
				<el-table-column prop="identifier" label="参数标识" width="120" />
				<el-table-column prop="required" label="参数必填" align="center" width="100">
					<template #default="scope">
					  <el-tag :type="scope.row.required == '1' ? 'danger' : 'info'">
						{{ scope.row.required == '1' ? "必填" : "可选" }}
					  </el-tag>
					</template>
				</el-table-column>
				<el-table-column prop="defaultValue" label="参数默认值" />
				<el-table-column label="操作" width="150" fixed="right">
					<template #default="{ row, $index }">
						<el-button link type="primary" @click="handleEditHeader($index, row)">编辑</el-button>
						<el-button link type="danger" @click="removeHeader($index)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
        </div>
      </template>
      
      <template v-if="formData.type === 'raw'">
        <div v-if="formData.rawType === 'Text'" class="raw-text-container">
          <el-input
            v-model="rawContent"
            type="textarea"
            :rows="10"
            :placeholder="getTextareaPlaceholder()"
            resize="none"
            @input="handleTextChange"
          />
          <div class="word-count">
            字数: {{ rawContent.length }}
          </div>
        </div>
		
		<div v-else-if="formData.rawType === 'JavaScript'" class="raw-editor-container">
		  <MonacoEditor
		    v-model="rawContent"
		    :options="jsEditorOptions"
		    language="javascript"
		    class="editor"
		    @change="handleJsChange"
		  />
		  <div class="editor-actions">
		    <el-button size="small" @click="formatJs">格式化</el-button>
		    <el-button size="small" @click="minifyJs">压缩</el-button>
		  </div>
		  <div v-if="jsError" class="error-message">
		    <el-alert :title="jsError" type="error" show-icon :closable="false" />
		  </div>
		</div>
        
        <div v-else-if="formData.rawType === 'JSON'" class="raw-editor-container">
<!--          <MonacoEditor
            v-model="rawContent"
            :options="jsonEditorOptions"
            language="json"
            class="editor"
            @change="handleJsonChange"
          />
          <div class="editor-actions">
            <el-button size="small" @click="formatJson">格式化</el-button>
            <el-button size="small" @click="minifyJson">压缩</el-button>
          </div>
          <div v-if="jsonError" class="error-message">
            <el-alert :title="jsonError" type="error" show-icon :closable="false" />
          </div> -->
		  
			<div class="header-content">
				<div style="margin-bottom: 0.3125rem;">
					<el-button type="primary" text size="small" @click="handleEditHeader(-1, null)">添加参数</el-button>
				</div>
				<el-table :data="content" border style="width: 100%">
					<el-table-column prop="name" label="参数名称" />
					<el-table-column prop="identifier" label="参数标识" width="120" />
					<el-table-column prop="required" label="参数必填" align="center" width="100">
						<template #default="scope">
						  <el-tag :type="scope.row.required == '1' ? 'danger' : 'info'">
							{{ scope.row.required == '1' ? "必填" : "可选" }}
						  </el-tag>
						</template>
					</el-table-column>
					<el-table-column prop="defaultValue" label="参数默认值" />
					<el-table-column label="操作" width="150" fixed="right">
						<template #default="{ row, $index }">
							<el-button link type="primary" @click="handleEditHeader($index, row)">编辑</el-button>
							<el-button link type="danger" @click="removeHeader($index)">删除</el-button>
						</template>
					</el-table-column>
				</el-table>
			</div>
		  
        </div>
        
        <div v-else-if="formData.rawType === 'XML'" class="raw-editor-container">
          <MonacoEditor
            v-model="rawContent"
            :options="xmlEditorOptions"
            language="xml"
            class="editor"
            @change="handleXmlChange"
          />
          <div class="editor-actions">
            <el-button size="small" @click="formatXml">格式化</el-button>
          </div>
          <div v-if="xmlError" class="error-message">
            <el-alert :title="xmlError" type="error" show-icon :closable="false" />
          </div>
        </div>
        
        <div v-else-if="formData.rawType === 'HTML'" class="raw-editor-container">
          <MonacoEditor
            v-model="rawContent"
            :options="htmlEditorOptions"
            language="html"
            class="editor"
            @change="handleHtmlChange"
          />
          <div class="editor-actions">
            <el-button size="small" @click="formatHtml">格式化</el-button>
            <el-tooltip content="在浏览器中预览" placement="top">
              <el-button size="small" @click="previeHtml">预览</el-button>
            </el-tooltip>
          </div>
        </div>
      </template>
    </el-form>
    
    <EditParamFieldDrawer
      ref="paramFieldDrawerRef"
      @success="handleParamFieldSuccess"
      @closed="handleParamFieldClosed"
      @parse-fields="handleParseJsonFields"
    />

    <el-dialog v-model="previewDialogVisible" title="HTML预览" width="80%">
      <iframe :srcdoc="rawContent" class="html-preview-frame"></iframe>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue';
import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus';
import MonacoEditor from '@/components/MonacoEditor/index.vue';
import EditParamFieldDrawer from '@/components/DataWorkflow/components/EditParamFieldDrawer.vue';
import { HttpBodyField } from '@/components/DataWorkflow/types/data-collect';

const props = defineProps<{ 
  data: HttpBodyField
}>();

const emit = defineEmits(['update:data', 'change', 'validate']);

const formData = ref<HttpBodyField>({ 
  ...props.data 
});

const paramsFormRef = ref<FormInstance>();
const jsonError = ref<string>('');
const xmlError = ref<string>('');
const jsError = ref<string>('');
const rawContent = ref<string>('');
const content = ref<any[]>([]);
const previewDialogVisible = ref(false);

const formRules = reactive<FormRules>({
  type: [
    { required: true, message: '请选择参数类型', trigger: 'blur' },
  ],
  rawType: [
    { required: true, message: '请选择raw类型', trigger: 'blur' },
  ]
});

// 编辑器配置
const jsonEditorOptions = {
  theme: 'vs-dark',
  automaticLayout: true,
  formatOnPaste: true,
  formatOnType: true,
  minimap: { enabled: false },
  scrollBeyondLastLine: false,
  tabSize: 2,
  fontSize: 14,
  language: 'json',
  autoClosingBrackets: 'always',
  autoClosingQuotes: 'always',
  suggestSelection: 'first',
  wordBasedSuggestions: true
};

const jsEditorOptions = {
  ...jsonEditorOptions,
  language: 'javascript',
  autoClosingBrackets: 'always',
  autoClosingQuotes: 'always',
  suggestSelection: 'first',
  wordBasedSuggestions: true
};

const xmlEditorOptions = {
  ...jsonEditorOptions,
  language: 'xml',
  autoClosingTags: true
};

const htmlEditorOptions = {
  ...jsonEditorOptions,
  language: 'html',
  autoClosingTags: true,
  emmet: true,
  suggestSelection: 'first',
  wordBasedSuggestions: true
};

// 获取文本区域placeholder
const getTextareaPlaceholder = () => {
  if (formData.value.rawType === 'JavaScript') {
    return '// 输入JavaScript代码';
  }
  return '请输入文本内容';
};

// 处理类型变化
const handleTypeChange = (val: string) => {
  if (val !== 'raw') {
    formData.value.rawType = undefined;
  } else {
    formData.value.rawType = 'JSON';
  }
  updateContent();
};

// 处理raw类型变化
const handleRawTypeChange = (val: string) => {
  switch (val) {
    // case 'JSON':
    //   rawContent.value = '{\n  \n}';
    //   break;
    case 'XML':
      rawContent.value = '<root>\n  \n</root>';
      break;
    case 'HTML':
      rawContent.value = '<!DOCTYPE html>\n<html>\n<head>\n  <title></title>\n</head>\n<body>\n\n</body>\n</html>';
      break;
    case 'JavaScript':
      rawContent.value = '// 输入JavaScript代码';
      break;
    default:
      rawContent.value = '';
  }
  jsonError.value = '';
  xmlError.value = '';
  jsError.value = '';
  updateContent();
};

// 更新内容数据
const updateContent = () => {
  if (['form-data', 'x-www-form-urlencoded'].includes(formData.value.type)) {
    formData.value.content = content.value;
  } else if (formData.value.type === 'raw') {
	  if(formData.value.rawType=='JSON'){
		  formData.value.content = content.value;
	  }else{
		  formData.value.content = rawContent.value;
	  }
  } else {
    formData.value.content = [];
  }
};

// 处理文本变化
const handleTextChange = () => {
  updateContent();
};

// 处理JavaScript变化
const handleJsChange = (value: string) => {
  try {
    if (value.trim()) {
      // 简单验证JavaScript语法
      new Function(value);
    }
    jsError.value = '';
    emit('validate', true);
  } catch (e) {
    jsError.value = `JavaScript语法错误: ${e}`;
    emit('validate', false);
  }
  updateContent();
};

// 格式化JavaScript
const formatJs = () => {
  try {
    if (rawContent.value.trim()) {
      // 使用Babel或其他格式化工具会更准确
      // 这里使用简单的正则格式化
      rawContent.value = rawContent.value
        .replace(/([{;])/g, '$1\n')
        .replace(/\n\s*\n/g, '\n')
        .replace(/^\s+|\s+$/g, '');
    } else {
      rawContent.value = '// 输入JavaScript代码';
    }
    jsError.value = '';
  } catch (e) {
    jsError.value = `无法格式化: ${e}`;
  }
};

// 压缩JavaScript
const minifyJs = () => {
  try {
    if (rawContent.value.trim()) {
      // 简单压缩 - 实际项目中应该使用专业压缩工具
      rawContent.value = rawContent.value
        .replace(/\/\/.*$/gm, '') // 删除单行注释
        .replace(/\/\*[\s\S]*?\*\//g, '') // 删除多行注释
        .replace(/\s+/g, ' ') // 合并多个空格
        .replace(/\s*([\{\}\[\]\(\)=,:;])\s*/g, '$1') // 删除符号周围的空格
        .trim();
    }
    jsError.value = '';
  } catch (e) {
    jsError.value = `无法压缩: ${e}`;
  }
};

// 处理JSON变化
const handleJsonChange = (value: string) => {
  updateContent();
};

// 格式化JSON
const formatJson = () => {
  try {
    if (rawContent.value.trim()) {
      const obj = JSON.parse(rawContent.value);
      rawContent.value = JSON.stringify(obj, null, 2);
    } else {
      rawContent.value = '{\n  \n}';
    }
    jsonError.value = '';
  } catch (e) {
    jsonError.value = `无法格式化: ${e}`;
  }
};

// 压缩JSON
const minifyJson = () => {
  try {
    if (rawContent.value.trim()) {
      const obj = JSON.parse(rawContent.value);
      rawContent.value = JSON.stringify(obj);
    }
    jsonError.value = '';
  } catch (e) {
    jsonError.value = `无法压缩: ${e}`;
  }
};

// 处理XML变化
const handleXmlChange = (value: string) => {
  if (formData.value.rawType === 'XML') {
    try {
      if (value.trim() && !isValidXml(value)) {
        throw new Error('XML格式不正确');
      }
      xmlError.value = '';
      emit('validate', true);
    } catch (e) {
      xmlError.value = `XML格式错误: ${e}`;
      emit('validate', false);
    }
  }
  updateContent();
};

// 格式化XML
const formatXml = () => {
  rawContent.value = formatXML(rawContent.value);
};

// 处理HTML变化
const handleHtmlChange = () => {
  updateContent();
};

// 格式化HTML
const formatHtml = () => {
  rawContent.value = formatHTML(rawContent.value);
};

// 预览HTML
const previeHtml = () => {
  previewDialogVisible.value = true;
};

// 简单的XML验证
const isValidXml = (xmlStr: string): boolean => {
  try {
    if (typeof DOMParser !== 'undefined') {
      const parser = new DOMParser();
      const dom = parser.parseFromString(xmlStr, 'text/xml');
      return dom.getElementsByTagName('parsererror').length === 0;
    }
    // 简单检查开始和结束标签是否匹配
    const trimmed = xmlStr.trim();
    return trimmed.startsWith('<') && trimmed.endsWith('>');
  } catch {
    return false;
  }
};

// 格式化XML
const formatXML = (xml: string): string => {
  if (!xml.trim().startsWith('<')) return xml;
  
  try {
    return xml
      .replace(/></g, '>\n<')
      .replace(/(<\/?[^>]+>)/g, '$1\n')
      .split('\n')
      .filter(line => line.trim())
      .map(line => {
        const match = line.match(/^\s*/);
        const indentLevel = match ? match[0].length : 0;
        return '  '.repeat(indentLevel / 2) + line.trim();
      })
      .join('\n');
  } catch {
    return xml;
  }
};

// 格式化HTML
const formatHTML = (html: string): string => {
  try {
    // 简单的HTML格式化
    return html
      .replace(/></g, '>\n<')
      .replace(/(<\/?[a-z][^>]*>)/gi, '$1\n')
      .split('\n')
      .filter(line => line.trim())
      .map(line => {
        const match = line.match(/^\s*/);
        const indentLevel = match ? match[0].length : 0;
        return '  '.repeat(indentLevel / 2) + line.trim();
      })
      .join('\n');
  } catch {
    return html;
  }
};

// 初始化数据
const initData = () => {
  if (props.data) {
    formData.value = { ...props.data };
    
    if (['form-data', 'x-www-form-urlencoded'].includes(formData.value.type)) {
      try {
        content.value = Array.isArray(formData.value.content) 
          ? formData.value.content 
          : typeof formData.value.content === 'string'
            ? JSON.parse(formData.value.content)
            : [];
      } catch (e) {
        console.error('解析 content 失败:', e);
        content.value = [];
      }
    } else if (formData.value.type === 'raw' && formData.value.rawType) {
	  if('JSON'==formData.value.rawType){
		  content.value = Array.isArray(formData.value.content)
		    ? formData.value.content 
		    : typeof formData.value.content === 'string'
		      ? JSON.parse(formData.value.content)
		      : [];
	  }else{
		  initRawContent();
	  }
    }
  }
};

// 初始化raw内容
const initRawContent = () => {
  switch (formData.value.rawType) {
  //   case 'JSON':
  //     try {
  //       rawContent.value = typeof formData.value.content === 'string'
  //         ? formData.value.content.trim() === ''
  //           ? '{}'
  //           : JSON.stringify(JSON.parse(formData.value.content), null, 2)
  //         : JSON.stringify(formData.value.content || {}, null, 2);
		
		// formData.value.content = content.value;
		  
		  
  //     } catch (e) {
  //       console.error('JSON解析失败:', e);
  //       rawContent.value = '{}';
  //     }
  //     break;
    case 'XML':
      rawContent.value = formatXML(formData.value.content || '<root></root>');
      break;
    case 'HTML':
      rawContent.value = formatHTML(formData.value.content || '<!DOCTYPE html>\n<html>\n<head>\n  <title></title>\n</head>\n<body>\n\n</body>\n</html>');
      break;
    case 'JavaScript':
      rawContent.value = formData.value.content || '// 输入JavaScript代码';
      break;
    default:
      rawContent.value = formData.value.content || '';
  }
};

// 监听props变化
watch(() => props.data, initData, { immediate: true, deep: true });

// 编辑参数相关逻辑
const paramFieldDrawerRef = ref();
const currentEditIndex = ref(-1);

const handleEditHeader = (index: number, row: any | null) => {
  currentEditIndex.value = index;
  paramFieldDrawerRef.value?.openDialog(index, row, row ? 'edit' : 'add');
};

const handleParamFieldSuccess = (index: number, data: any) => {
  if (index === -1) {
    content.value.push(data);
  } else {
    content.value[index] = data;
  }
  updateContent();
};

const removeHeader = (index: number) => {
  content.value.splice(index, 1);
  updateContent();
};

const handleParamFieldClosed = () => {
  currentEditIndex.value = -1;
};

const handleParseJsonFields = (fields: any[]) => {
  const headerPaths = new Set(content.value.map(f => f.identifier));
  const newHeaderFields = fields.filter(f => !headerPaths.has(f.identifier));
  
  if (newHeaderFields.length === 0) {
    ElMessage.warning('没有新的字段需要添加');
    return;
  }
  
  content.value.push(...newHeaderFields);
  ElMessage.success(`成功添加 ${newHeaderFields.length} 个字段`);
  updateContent();
};

// 暴露方法
defineExpose({
  validate: async () => {
    try {
      await paramsFormRef.value?.validate();
      
      // 额外验证JSON/XML/JavaScript格式
      if (formData.value.type === 'raw') {
        if (formData.value.rawType === 'JSON' && jsonError.value) {
          throw new Error(jsonError.value);
        }
        if (formData.value.rawType === 'XML' && xmlError.value) {
          throw new Error(xmlError.value);
        }
        if (formData.value.rawType === 'JavaScript' && jsError.value) {
          throw new Error(jsError.value);
        }
      }
      
      return true;
    } catch (e) {
      ElMessage.error(e || '验证失败');
      return false;
    }
  },
  getData: () => {
    return {
      ...formData.value,
      content: formData.value.type === 'raw' && formData.value.rawType!='JSON'  ? rawContent.value : content.value
    };
  },
  reset: () => {
    formData.value = {
      type: 'none',
      rawType: 'JSON',
      content: []
    };
    content.value = [];
    rawContent.value = '';
    jsonError.value = '';
    xmlError.value = '';
    jsError.value = '';
  }
});
</script>

<style scoped>
.editor {
  height: 400px;
  min-height: 250px;
  width: 100%;
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  margin-bottom: 10px;
}

.error-message {
  margin-top: 10px;
  margin-bottom: 15px;
}

.raw-text-container {
  position: relative;
}

.word-count {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
}

.editor-actions {
  margin-top: 10px;
  display: flex;
  gap: 10px;
}

.header-content {
  margin-top: 15px;
}

.html-preview-frame {
  width: 100%;
  height: 500px;
  border: 1px solid #eee;
  border-radius: 4px;
}
</style>